/**
 * QUANSHI.com Inc.
 * Copyright (c) 2016-2017 All Rights Reserved.
 */
package com.quanshi.scheduler.job.web.controller;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.quanshi.scheduler.core.base.Ret;
import com.quanshi.scheduler.core.biz.model.HandleCallbackParam;
import com.quanshi.scheduler.core.biz.model.RegistryParam;
import com.quanshi.scheduler.core.utils.AdminApiUtils;
import com.quanshi.scheduler.core.utils.FastJSONUtils;
import com.quanshi.scheduler.job.biz.service.TriggerInfoService;
import com.quanshi.scheduler.job.biz.service.TriggerLogService;
import com.quanshi.scheduler.job.biz.service.TriggerRegistryService;
import com.quanshi.scheduler.job.dal.entity.TriggerLog;

/**
 * 处理器交互接口
 * 
 * @author yanxiang.huang 2017-07-12 15:07:52
 */
@Controller
public class ApiController extends BaseController {

    @Resource
    private TriggerRegistryService triggerRegistryService;

    @Resource
    private TriggerLogService      triggerLogService;

    @Resource
    private TriggerInfoService     triggerInfoService;

    /**
     * 处理器注册接口
     *
     * @param registryParam
     * @return
     */
    @RequestMapping(value = AdminApiUtils.REGISTRY, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Ret<String> registry(@RequestBody RegistryParam registryParam) {
        logger.debug("access registry. param:{}.", FastJSONUtils.toJSONString(registryParam));
        boolean res = triggerRegistryService.update(registryParam.getRegistGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
        if (!res) {
            triggerRegistryService.save(registryParam.getRegistGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
        }
        logger.debug("access registry end.");
        return Ret.SUCCESS;
    }

    /**
     * 处理器回调接口
     *
     * @param registryParam
     * @return
     */
    @RequestMapping(value = AdminApiUtils.CALLBACK, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Ret<String> callback(@RequestBody List<HandleCallbackParam> callbackParamList) {
        for (HandleCallbackParam handleCallbackParam : callbackParamList) {
            Ret<String> callbackResult = callback(handleCallbackParam);
            logger.info("apiController.callback {}, handleCallbackParam={}, callbackResult={}.", (callbackResult.getCode() == Ret.SUCCESS_CODE ? "success" : "fail"),
                handleCallbackParam, callbackResult);
        }
        return Ret.SUCCESS;
    }

    /**
     * 回调处理
     *
     * @param handleCallbackParam
     * @return
     */
    private Ret<String> callback(HandleCallbackParam handleCallbackParam) {
        TriggerLog log = triggerLogService.get(handleCallbackParam.getLogId());
        if (log == null) {
            return new Ret<>(Ret.FAIL_CODE, "log item can't be found.");
        }
        // trigger success, to trigger child job, and avoid repeat trigger child
        // job
        String childTriggerMsg = "";
        if (Ret.SUCCESS_CODE == handleCallbackParam.getExecuteResult().getCode() && Ret.SUCCESS_CODE != log.getHandleCode()) {
            childTriggerMsg = triggerInfoService.triggerChild(log.getJobId());
        }
        // handle msg
        StringBuffer handleMsg = new StringBuffer();
        if (log.getHandleMsg() != null) {
            handleMsg.append(log.getHandleMsg()).append("<br>");
        }
        if (handleCallbackParam.getExecuteResult().getMsg() != null) {
            handleMsg.append(handleCallbackParam.getExecuteResult().getMsg());
        }
        if (childTriggerMsg != null) {
            handleMsg.append("<br>子任务触发备注：").append(childTriggerMsg);
        }
        // success, save log
        log.setHandleTime(new Date());
        log.setHandleCode(handleCallbackParam.getExecuteResult().getCode());
        log.setHandleMsg(handleMsg.toString());
        triggerLogService.update(log);
        return Ret.SUCCESS;
    }

}
